package com.hamilton.erik.pt.core.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.hamilton.erik.pt.core.dao.FeedingDAO;
import com.hamilton.erik.pt.core.db.H2JdbcAccess;
import com.hamilton.erik.pt.core.model.Feeding;
import com.hamilton.erik.pt.core.util.SqlUtil;

public class H2FeedingDAO implements FeedingDAO {

	private final String FEEDING_DB_TABLE = "APPLICATION.FEEDING";
	
	private final String INSERT_FEEDING = 
			String.format(
				"INSERT INTO %s (ANIMAL_ID, FEEDING_ITEM, MEASUREMENT, " +
				"MEASUREMENT_UNIT, FEEDING_TIME) " +
				"VALUES (?, ?, ?, ?, ?)",
				FEEDING_DB_TABLE);
	
	private final String UPDATE_FEEDING =
			String.format(
				"UPDATE %s SET FEEDING_ITEM=?, MEASUREMENT=?, MEASUREMENT_UNIT=?, " +
				"FEEDING_TIME=? WHERE ID=?",
				FEEDING_DB_TABLE);
	
	private final String DELETE_FEEDING =
			String.format("DELETE FROM %s WHERE ID=?", FEEDING_DB_TABLE);
	
	private final String GET_ALL_FEEDINGS =
			String.format(
				"SELECT * FROM %s WHERE ANIMAL_ID = ?", FEEDING_DB_TABLE);
	
	private final String DELETE_ALL_FEEDINGS =
			String.format("DELETE FROM %s WHERE ANIMAL_ID=?", FEEDING_DB_TABLE);
	
	@Override
	public int insertFeeding(Feeding feeding) throws SQLException {

		int insertedRow = -1;
		Connection conn = null;
		
		try {
			conn = H2JdbcAccess.getInstance().getConnection();
			conn.setAutoCommit(false);
						
			PreparedStatement stmt = conn.prepareStatement(INSERT_FEEDING);
		
			stmt.setLong(1, feeding.getAnimalId());
			stmt.setString(2, feeding.getFeedingItem());
			SqlUtil.setDoubleOrNull(3, stmt, feeding.getMeasurement());
			SqlUtil.setStringOrNull(4, stmt, feeding.getMeasurementUnit());
			stmt.setString(5, feeding.getTimestamp());
			
			insertedRow = stmt.executeUpdate();
			
			conn.commit();

			return insertedRow;
		} catch (SQLException e) {
			throw e;
		} finally {
			if(conn != null) try { conn.close(); } catch (Exception ignore) {}
		}
	}

	@Override
	public boolean deleteFeeding(Long feedingId) throws SQLException {

		int returnValue = -1;
		Connection conn = null;
		
		try {
			conn = H2JdbcAccess.getInstance().getConnection();
			conn.setAutoCommit(false);
						
			PreparedStatement stmt = conn.prepareStatement(DELETE_FEEDING);

			stmt.setLong(1, feedingId);
			
			returnValue = stmt.executeUpdate();
			
			conn.commit();

			if(returnValue > 0) {
				return true;
			}
		} catch (SQLException e) {
			throw e;
		} finally {
			if(conn != null) try { conn.close(); } catch (Exception ignore) {}
		}
		
		return false;
	}

	@Override
	public Feeding findFeeding(Feeding feeding) throws SQLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int updateFeeding(Feeding feeding) throws SQLException {

		int updatedRow = -1;
		Connection conn = null;
		
		try {
			conn = H2JdbcAccess.getInstance().getConnection();
			conn.setAutoCommit(false);
						
			PreparedStatement stmt = conn.prepareStatement(UPDATE_FEEDING);
			
			stmt.setString(1, feeding.getFeedingItem());
			SqlUtil.setDoubleOrNull(2, stmt, feeding.getMeasurement());
			SqlUtil.setStringOrNull(3, stmt, feeding.getMeasurementUnit());
			stmt.setString(4, feeding.getTimestamp());
			stmt.setLong(5, feeding.getId());
			
			updatedRow = stmt.executeUpdate();
			
			conn.commit();

			return updatedRow;
		} catch (SQLException e) {
			throw e;
		} finally {
			if(conn != null) try { conn.close(); } catch (Exception ignore) {}
		}
	}

	@Override
	public List<Feeding> getAllFeedings(Long animalId) throws SQLException {

		List<Feeding> feedings = new ArrayList<Feeding>();
		Connection conn = null;
		
		try {
			conn = H2JdbcAccess.getInstance().getConnection();
						
			PreparedStatement stmt = conn.prepareStatement(GET_ALL_FEEDINGS);
		
			stmt.setLong(1, animalId);
			
			ResultSet rs = stmt.executeQuery();
			
			while(rs.next()) {
				Feeding newFeeding = new Feeding();
	
				newFeeding.setId(rs.getLong(1));
				newFeeding.setAnimalId(rs.getLong(2));
				newFeeding.setFeedingItem(rs.getString(3));
				newFeeding.setMeasurement(rs.getDouble(4));
				newFeeding.setMeasurementUnit(rs.getString(5));
				newFeeding.setTimestamp(rs.getString(6));
				
				feedings.add(newFeeding);
			}
			
			return feedings;
			
		} catch (SQLException e) {
			throw e;
		} finally {
			if(conn != null) try { conn.close(); } catch (Exception ignore) {}
		}
	}

	@Override
	public boolean deleteAllFeedings(Long animalId) throws SQLException {

		int returnValue = -1;
		Connection conn = null;
		
		try {
			conn = H2JdbcAccess.getInstance().getConnection();
			conn.setAutoCommit(false);
						
			PreparedStatement stmt = conn.prepareStatement(DELETE_ALL_FEEDINGS);

			stmt.setLong(1, animalId);
			
			returnValue = stmt.executeUpdate();
			
			conn.commit();

			if(returnValue > 0) {
				return true;
			}
		} catch (SQLException e) {
			throw e;
		} finally {
			if(conn != null) try { conn.close(); } catch (Exception ignore) {}
		}
		
		return false;
	}
}
